﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.Gateway;
using Wicture.DbRESTFul.SQL;
using Wicture.EPC.Service.Etka;
using Wicture.EPC.Service.Etka.QueryInterceptors.Interceptors;
using Xunit;

namespace Wicture.QPZS.Test
{
    public class FullVinDataExport
    {
        private ETKAQueryInterceptor etkaInterpreter = new ETKAQueryInterceptor();

        protected DbRESTFulRepository GetRepository(Brand model)
        {
            var connString = ConnectionHelper.Get(model.brandCode);
            var repository = new DbRESTFulRepository(new SqlConnectionManager { ReadConnectionString = connString });

            return repository;
        }

        private void Setup()
        {
            ConfigurationManager.Load($@"{Consts.GetPath()}\Services\Wicture.EPC.Service.Etka\config.json");

            ConfigurationManager.Settings.Document[CSISetting.Name]["Path"] = $@"{Consts.GetPath()}\Services\Wicture.EPC.Service.Etka\CSI";
            CSILoader.Instance.Load(ConfigurationManager.Settings, true);

            DbGatewayManager.Current = new TestDbGateway();
        }

        [Fact]
        public void Export()
        {
            Setup();
            var brandCode = "vw";
            var repository = GetRepository(new Brand { brandCode = brandCode });
            var vins = new[] { "LSVWL2182GN281861", "LFV2A1BS9G4563781" };

            foreach (var vin in vins)
            {
                var vinInfo = etkaInterpreter.QueryModel(repository, JObject.FromObject(new { vin, brandCode })) as Get_Model_InfoResult;

                List<Query_MainGroupResult> mainGroups = etkaInterpreter.QueryMainGroup(repository, JObject.FromObject(new { brandCode, vin })) as List<Query_MainGroupResult>;

                var exportedParts = new List<ExportPart>();

                foreach (var mainGroup in mainGroups)
                {
                    List<Query_SubGroupResult> subGroups =
                        etkaInterpreter.QuerySubGroup(repository, JObject.FromObject(new
                        {
                            brandCode,
                            mainGroup.id,
                            vin,
                            vinInfo.selectorId
                        })) as List<Query_SubGroupResult>;

                    foreach (var subGroup in subGroups)
                    {
                        List<Query_PartsResult> parts =
                            etkaInterpreter.QueryParts(repository, JObject.FromObject(new { brandCode, vin, subGroup.id })) as List<Query_PartsResult>;

                        exportedParts.AddRange(parts.Where(p => !string.IsNullOrEmpty(p.id) && p.belongToVin).Select(part =>
                        new ExportPart
                        {
                            id = part.id,
                            mainGroupName = mainGroup.name?.Replace("$$", " "),
                            subGroupName = subGroup.name?.Replace("$$", " "),
                            subGroupCode = subGroup.code,
                            subGroupImageSN = subGroup.imageSN,
                            partCode = part.partCode,
                            partName = part.partName?.Replace("$$", " "),
                            imageSN = part.imageSN,
                            quantity = part.quantity,
                            price = part.price,
                            description = part.description?.Replace("$$", " "),
                            notes = string.Join(';', new[] { part.notes, part.modelNotes }).Trim(';')?.Replace("$$", " ")
                        }));
                    }
                }

                WriteToCsvFile(exportedParts, $@"D:\QPZS\ETKA\data\{vin}.csv");
            }
        }

        private static void WriteToCsvFile(List<ExportPart> parts, string filePath)
        {
            StringBuilder fileContent = new StringBuilder();

            var pis = typeof(ExportPart).GetProperties();
            var headerType = typeof(ExportPart.HeaderAttribute);
            foreach (var pi in pis)
            {
                var header = pi.GetCustomAttributes(headerType, false).FirstOrDefault();
                
                if(header != null)
                {
                    fileContent.Append((header as ExportPart.HeaderAttribute).Name + ",");
                }
                else
                {
                    fileContent.Append(pi.Name + ",");
                }
            }

            fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);

            foreach (var part in parts)
            {
                foreach (var pi in pis)
                {
                    fileContent.Append("\"" + pi.GetValue(part) + "\",");
                }

                fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
            }

            System.IO.File.WriteAllText(filePath, fileContent.ToString(), Encoding.Default);
        }
    }

    public class ExportPart
    {
        [Header("配件主键Id")]
        public string id { get; set; }

        [Header("零件主组名称")]
        public string mainGroupName { get; set; }

        [Header("零件子组名称")]
        public string subGroupName { get; set; }

        [Header("图号")]
        public string subGroupCode { get; set; }

        [Header("图号名称")]
        public string subGroupImageSN { get; set; }

        [Header("图中序号")]
        public string imageSN { get; set; }

        [Header("配件编码")]
        public string partCode { get; set; }

        [Header("零件名称")]
        public string partName { get; set; }

        [Header("4s店价")]
        public decimal? price { get; set; }

        [Header("每车用量")]
        public string quantity { get; set; }

        [Header("简略备注")]
        public string description { get; set; }

        [Header("详细备注")]
        public string notes { get; set; }

        public class HeaderAttribute : Attribute
        {
            public string Name { get; set; }
            public HeaderAttribute(string name)
            {
                Name = name;
            }
        }
    }
}
